#ifndef _OBJECT_ARCHIVE_H_
#define _OBJECT_ARCHIVE_H_

#include <buildspec.h>
#include <Geometry/IFileSerialisable.h>
#include <Geometry/SRS.h>
#include <Geometry/boost_serialize_includes.hpp>
#include <map>
#include <Utils/Converter.h>

#include <boost/shared_ptr.hpp>
#include <boost/pointer_cast.hpp>

namespace GST{
namespace Geometry{

struct GST_API_EXPORT ObjectArchive 
{	
	ObjectArchive();

	typedef std::map<std::string,std::string, Utils::UpperCaseCompare> VariousPropertyMap;

	///@name members (Do not forget to change class version when adding a new one)
	//@{
		std::string objectName;
		std::string geometryFile;
		IFileSerialisable::FileType geometryFileType;
		std::string propertyFile;
		std::string lockid;
		Geometry::SRSPtr srs;
		VariousPropertyMap various_properties;
	//@}

	///@name getters/setters
	//@{
		bool isLocked() const;
		void addProperty(const std::string& key, const std::string & value);
		void removeProperty(const std::string & key);
		std::string getValue(const std::string & key);
		std::string ToIdentityString() const;
		void updateRelativePathsToGlobalPath(const std::string & globalPath, bool throwIfLinkedFilesAreNotExistent = true );
	//@}

	///to file
	void toFile(const std::string & filename);
	static boost::shared_ptr<ObjectArchive> FromFile(const std::string & filename, bool throwIfLinkedFilesAreNotExistent = true);

	///boost serialization access
	template <typename Archive> 
	void serialize(Archive &ar, const unsigned int version);
};
typedef boost::shared_ptr<ObjectArchive> ObjArchivePtr;

template <typename Archive> 
void ObjectArchive::serialize(Archive &ar, const unsigned int version)
{
	ar & BOOST_SERIALIZATION_NVP( objectName ); 
	ar & BOOST_SERIALIZATION_NVP( geometryFile );
	ar & BOOST_SERIALIZATION_NVP( geometryFileType );
	ar & BOOST_SERIALIZATION_NVP( propertyFile );
	ar & BOOST_SERIALIZATION_NVP( lockid );

	registerSRSTypes<Archive>(ar); 
	if(Archive::is_saving::value)
	{
		if(srs && srs->getType() == SRS::GSTID) 
		{	
			//make a copy to base class
			GSTSRSRefPtr srsp( new GSTSRSRef( boost::static_pointer_cast<GSTSRSRef>(srs)->getID() ) );
			ar & boost::serialization::make_nvp("srsp",srsp);
		} else {
			ar & boost::serialization::make_nvp("srsp",srs);
		}
	} 
	else 
	{
		//is loading
		ar & boost::serialization::make_nvp("srsp",srs);
	}

	ar & BOOST_SERIALIZATION_NVP( various_properties );
}


//-----------------------------------------------------------------------------------------------------------#


struct GST_API_EXPORT SessionArchive
{
	SessionArchive()
	{

	}

	std::vector<ObjArchivePtr> objectArchives;

	///to file
	static void ToFile(boost::shared_ptr<SessionArchive> sarchive, const std::string & filename);
	static boost::shared_ptr<SessionArchive> FromFile(const std::string & filename, bool throwIfLinkedFilesAreNotExistent = true);

	///boost serialization access
	template <typename Archive> 
	void serialize(Archive &ar, const unsigned int version);
};
typedef boost::shared_ptr<SessionArchive> SessionArchivePtr;

template <typename Archive> 
void SessionArchive::serialize(Archive &ar, const unsigned int version)
{
	ar & boost::serialization::make_nvp("objectArchives", this->objectArchives);
}

}// namespace Geometry
}// namespace GST

BOOST_CLASS_EXPORT_KEY(GST::Geometry::ObjectArchive);
BOOST_CLASS_EXPORT_KEY(GST::Geometry::SessionArchive);

BOOST_CLASS_VERSION(GST::Geometry::ObjectArchive, 2) 
BOOST_CLASS_VERSION(GST::Geometry::SessionArchive, 1)

#endif //_OBJECT_ARCHIVE_H_
